<?php


namespace App\Service;

use Firebase\JWT\JWT;
use Exception;
use Ramsey\Uuid\Uuid;
use RuntimeException;

class JwtAuth {

    /**
     * 加密算法
     * @var string
     */
    private $_singAlgorithm = 'RS256';
    /**
     * 加密私钥
     * @var false|string
     */
    private $_privateKey;
    /**
     * 解密公钥
     * @var false|string
     */
    private $_publicKey;
    /**
     * jwt发布人
     * @var \EchoPHP\Foundation\Container|mixed|object
     */
    private $_iss;
    /**
     * jwt有效期
     * @var \EchoPHP\Foundation\Container|mixed|object
     */
    private $_exp;

    public function __construct() {
        try {
            $this->_publicKey = file_get_contents(config('app.jwt.public_key'));
            $this->_privateKey = file_get_contents(config('app.jwt.private_key'));
        } catch (Exception $e) {
            throw new RuntimeException('请确认JWT密钥对是否配置正确');
        }
        $this->_iss = config('app.jwt.issuer', '51rpo');
        $this->_exp = config('app.jwt.expire', 7200);
    }

    /**
     * 生成jwt
     * @param array $data 存储数据
     * @param int $expire token有效期， 秒
     * @param null $uuid token标识，此处默认值则自动根据时间戳生成唯一标识
     * @return string
     * @throws Exception
     */
    public function encode(array $data, $expire = 0, $uuid = null) {
        if (is_null($uuid) && !isset($data['jti'])) {
            $data['jti'] = Uuid::uuid1()->toString();
        }
        $data['iss'] = $this->_iss;
        $current = time();
        $data['iat'] = $current;
        $data['exp'] = $current + ($expire > 0 ? (int)$expire : $this->_exp);
        return JWT::encode($data, $this->_privateKey, $this->_singAlgorithm);
    }

    /**
     * jwt内容解密
     * @param $jwt
     * @return array
     */
    public function decode($jwt) {
        return (array)JWT::decode($jwt, $this->_publicKey, [$this->_singAlgorithm]);
    }
}